/***************************************************************************
* Copyright  Faraday Technology Corp 2002-2003.  All rights reserved.      *
*--------------------------------------------------------------------------*
* Name:watch_dog.c                                                         *
* Description: Watch Dog Timer library routine                             *
* Author: Charles Tsai                                                     *
****************************************************************************/
#include "unione_lite.h"
#include "watch_dog.h"
#include "DrvUART010.h"
#include "interrupt.h"

#define WDT_FTWDT010_PA_BASE WDT_FTWDT010_0_PA_BASE
#ifndef TRUE
#define TRUE	1
#endif

#ifndef FALSE
#define FALSE	0
#endif


void fLib_WatchDog_Enable(void)
{
    UINT32 tmp;

	tmp = inw(WDT_FTWDT010_PA_BASE + WD_CR);	
	tmp &= 0x1F;
    tmp |= WdEnable;
    outw(WDT_FTWDT010_PA_BASE + WD_CR, tmp);
}

void fLib_WatchDog_Disable(void)
{
    UINT32 tmp;

	tmp = inw(WDT_FTWDT010_PA_BASE + WD_CR);	
	tmp &= 0x1F;
    tmp &= (~WdEnable); 
    outw(WDT_FTWDT010_PA_BASE + WD_CR, tmp);
}


void fLib_WatchDog_ReStart(void)
{
    outw(WDT_FTWDT010_PA_BASE + WD_Restart,WD_AUTO_RELOAD);  
}


void fLib_WatchDog_SetAutoReLoad(UINT32 value)
{
    outw(WDT_FTWDT010_PA_BASE + WD_Load,value);			
}


void fLib_WatchDog_ClearStatus(void)
{
    outw(WDT_FTWDT010_PA_BASE + WD_Clear,1);// clear watchdog status bit
}


void fLib_WatchDog_SetIntCounter(UINT8 Counter)
{
    outw(WDT_FTWDT010_PA_BASE + WD_Intrlen,Counter); 
}


void fLib_WatchDog_SysIntEnable(void)
{
    outw(WDT_FTWDT010_PA_BASE + WD_CR, WdIntEnable | WdEnable);  
}


void fLib_WatchDog_SysIntDisable(void)
{
    unsigned temp;
    UINT32 tmp;

    temp = ~ WdIntEnable;
    temp &= 0x1F; 

	tmp = inw(WDT_FTWDT010_PA_BASE + WD_CR);	
	tmp &= temp; 
	    
    outw(WDT_FTWDT010_PA_BASE + WD_CR, tmp); 
}


void fLib_WatchDog_SysResetEnable(void)
{
    UINT32 tmp;

	tmp = inw(WDT_FTWDT010_PA_BASE + WD_CR);
	tmp &= 0x1F;
	tmp |= WdReset ; 
    outw(WDT_FTWDT010_PA_BASE + WD_CR,tmp);
}

void fLib_WatchDog_SysResetDisable(void)
{
    unsigned temp;
    UINT32 tmp;    

    temp = ~ WdReset;
    temp &= 0x1F; 
    
	tmp = inw(WDT_FTWDT010_PA_BASE + WD_CR);	
	tmp &= temp; 
	    
    outw(WDT_FTWDT010_PA_BASE + WD_CR, tmp); 
}


BOOL fLib_WatchDog_IsCounterZero()
{
    UINT32 tmp;

	tmp = inw(WDT_FTWDT010_PA_BASE + WD_Status);
    if (tmp == 1)
    	return TRUE;
    else
    	return FALSE;
}


UINT32 fLib_WatchDog_ReadCounter()
{
	return inw(WDT_FTWDT010_PA_BASE + WD_Counter);
}

void watchdog_isr(UINT32 IntNum)
{
	fLib_printf("watchdog timeout \r\n");
	fLib_WatchDog_ClearStatus();
	fLib_WatchDog_ReStart();
}

void WatchDogStart(UINT32 reload_sec)
{
    /* 10 sec at last */
    if (reload_sec <= 10) {
       reload_sec = 10;
    }
#if 1
	if(fLib_ConnectInt(FTWDT010_0_IRQ, watchdog_isr) == 0){
		fLib_printf("Fail to register watchdog_isr \r\n");
		return;
	}
	fLib_SetIntTrig(FTWDT010_0_IRQ,0,0);//level,high
	fLib_EnableInt(FTWDT010_0_IRQ);
#endif
	fLib_WatchDog_SetIntCounter(0xff);      //signal asserting 256 clock cycles
	fLib_WatchDog_SetAutoReLoad(reload_sec*APB_CLK);
	fLib_WatchDog_ReStart();
	fLib_WatchDog_SysIntEnable();           //Enable WD Int
	fLib_WatchDog_SysResetEnable();
	fLib_WatchDog_Enable();                 //Enable WD
}

